#include <stdio.h>

/* 主函数 */
int main() {
    /* 定义常量m和n，表示二维数组的行数和列数 */
    const int m = 3, n = 3;
    /* 初始化变量v，用于填充数组 */
    int v = 1;
    /* 定义一个m行n列的二维数组arr */
    int arr[m][n];
    /* 使用双重循环为数组赋值，从1开始，逐个增加 */
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            arr[i][j] = v++;
        }
    }

    /* 使用双重循环打印数组的每个元素 */
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
        }
    }

    /* 定义常量i和j，用于后续地址计算 */
    const int i = 1, j = 1;
    /* 打印数组arr的地址 */
    printf("--------------------------------------------------------------------------------\n");
    printf("&arr                                                            = %p\n", &arr);
    printf("--------------------------------------------------------------------------------\n");
    /* 打印数组arr第一个元素的地址 */
    printf("&arr[0][0]                                                      = %p\n", &arr[0][0]);
    printf("--------------------------------------------------------------------------------\n");
    /* 打印数组arr[i][j]的地址 */
    printf("&arr[%d][%d]                                                      = %p\n", i, j, &arr[i][j]);
    printf("--------------------------------------------------------------------------------\n");
    /* 计算并打印通过数组地址和元素下标计算得到的arr[i][j]的地址 */
    printf("&arr[%d][%d] = &arr + (i * n + j) * sizeof(int)                   = %p\n", i, j, &arr + (i * n + j) * sizeof(int));
    printf("--------------------------------------------------------------------------------\n");
    /* 计算并打印通过数组地址和元素下标计算得到的arr[i][j]的地址 */
    printf("&arr[%d][%d] = &arr + i * n * sizeof(int) + j * sizeof(int)       = %p\n", i, j, &arr + i * n * sizeof(int) + j * sizeof(int));
    printf("--------------------------------------------------------------------------------\n");
    /* 计算并打印通过数组第一个元素的地址和元素下标计算得到的arr[i][j]的地址 */
    printf("&arr[%d][%d] = &arr[0][0] + (i * n + j) * sizeof(int)             = %p\n", i, j, &arr[0][0] + (i * n + j) * sizeof(int));
    printf("--------------------------------------------------------------------------------\n");
    /* 计算并打印通过数组第一个元素的地址和元素下标计算得到的arr[i][j]的地址 */
    printf("&arr[%d][%d] = &arr[0][0] + i * n * sizeof(int) + j * sizeof(int) = %p\n", i, j, &arr[0][0] + i * n * sizeof(int) + j * sizeof(int));
    printf("--------------------------------------------------------------------------------\n");

    return 0;
}
